package com.example.controller;

import com.example.model.Appointment;
import com.example.repository.AppointmentRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/appointments")
@Tag(name = "预约管理", description = "预约的创建、查询、更新和管理")
public class AppointmentController {
    
    @Autowired
    private AppointmentRepository appointmentRepository;

    @PostMapping
    @Operation(summary = "创建预约")
    public ResponseEntity<Appointment> createAppointment(@Valid @RequestBody Appointment appointment) {
        Appointment createdAppointment = appointmentRepository.save(appointment);
        return ResponseEntity.ok(createdAppointment);
    }

    @GetMapping
    @Operation(summary = "获取预约列表")
    public ResponseEntity<Page<Appointment>> getAllAppointments(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "appointmentTime") String sortBy,
            @RequestParam(defaultValue = "asc") String sortDir,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String type) {
        
        Sort sort = Sort.by(Sort.Direction.fromString(sortDir), sortBy);
        Pageable pageable = PageRequest.of(page, size, sort);
        
        if (status != null && !status.isEmpty()) {
            try {
                Appointment.AppointmentStatus appointmentStatus = Appointment.AppointmentStatus.valueOf(status.toUpperCase());
                return ResponseEntity.ok(appointmentRepository.findByStatus(appointmentStatus, pageable));
            } catch (IllegalArgumentException e) {
                return ResponseEntity.badRequest().build();
            }
        }
        
        return ResponseEntity.ok(appointmentRepository.findAll(pageable));
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取预约详情")
    public ResponseEntity<Appointment> getAppointmentDetail(@PathVariable Long id) {
        return appointmentRepository.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新预约")
    public ResponseEntity<Appointment> updateAppointment(
            @PathVariable Long id,
            @Valid @RequestBody Appointment appointment) {
        return appointmentRepository.findById(id)
                .map(existingAppointment -> {
                    appointment.setId(id);
                    Appointment updatedAppointment = appointmentRepository.save(appointment);
                    return ResponseEntity.ok(updatedAppointment);
                })
                .orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除预约")
    public ResponseEntity<Void> deleteAppointment(@PathVariable Long id) {
        if (appointmentRepository.existsById(id)) {
            appointmentRepository.deleteById(id);
            return ResponseEntity.ok().build();
        }
        return ResponseEntity.notFound().build();
    }

    @PutMapping("/{id}/confirm")
    @Operation(summary = "确认预约")
    public ResponseEntity<Appointment> confirmAppointment(
            @PathVariable Long id,
            @RequestBody(required = false) Map<String, String> confirmData) {
        
        return appointmentRepository.findById(id)
                .map(appointment -> {
                    appointment.setStatus(Appointment.AppointmentStatus.CONFIRMED);
                    appointment.setConfirmedAt(LocalDateTime.now());
                    
                    if (confirmData != null && confirmData.containsKey("notes")) {
                        appointment.setConfirmNotes(confirmData.get("notes"));
                    }
                    
                    Appointment updatedAppointment = appointmentRepository.save(appointment);
                    return ResponseEntity.ok(updatedAppointment);
                })
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}/cancel")
    @Operation(summary = "取消预约")
    public ResponseEntity<Appointment> cancelAppointment(
            @PathVariable Long id,
            @RequestBody(required = false) Map<String, String> cancelData) {
        
        return appointmentRepository.findById(id)
                .map(appointment -> {
                    appointment.setStatus(Appointment.AppointmentStatus.CANCELLED);
                    
                    if (cancelData != null && cancelData.containsKey("reason")) {
                        appointment.setNotes(appointment.getNotes() + "\n取消原因: " + cancelData.get("reason"));
                    }
                    
                    Appointment updatedAppointment = appointmentRepository.save(appointment);
                    return ResponseEntity.ok(updatedAppointment);
                })
                .orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/today")
    @Operation(summary = "获取今日预约")
    public ResponseEntity<List<Appointment>> getTodayAppointments() {
        LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        List<Appointment> todayAppointments = appointmentRepository.findTodayAppointments(startOfDay, endOfDay);
        return ResponseEntity.ok(todayAppointments);
    }

    @GetMapping("/upcoming")
    @Operation(summary = "获取即将到期的预约")
    public ResponseEntity<List<Appointment>> getUpcomingAppointments() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneHourLater = now.plusHours(1);
        List<Appointment> upcomingAppointments = appointmentRepository.findUpcomingAppointments(now, oneHourLater);
        return ResponseEntity.ok(upcomingAppointments);
    }

    @GetMapping("/statistics")
    @Operation(summary = "获取预约统计")
    public ResponseEntity<Map<String, Object>> getAppointmentStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 各状态预约统计
        List<Object[]> statusStats = appointmentRepository.countByStatus();
        statistics.put("statusStatistics", statusStats);
        
        // 总预约数
        long totalAppointments = appointmentRepository.count();
        statistics.put("totalAppointments", totalAppointments);
        
        // 今日预约数
        LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        List<Appointment> todayAppointments = appointmentRepository.findTodayAppointments(startOfDay, endOfDay);
        statistics.put("todayAppointments", todayAppointments.size());
        
        // 待确认预约数
        List<Appointment> pendingAppointments = appointmentRepository.findByStatusOrderByCreatedAtDesc(Appointment.AppointmentStatus.PENDING);
        statistics.put("pendingAppointments", pendingAppointments.size());
        
        return ResponseEntity.ok(statistics);
    }
}
